using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Text;
using System.Threading;
using System.IO;
using RandomRat.Data;

namespace RandomRat {


	public class Form1 : System.Windows.Forms.Form {

		#region VARS

		RandomSetGenerator rndSetGen;		// Class which does all the work in generating valid sets
		Thread workerThread;				// Thread used to generate sets (while keeping UI working, alowing aborts, etc.)
		Thread workerThread2;				// Thread used for reading critieral XML files on startup
			
		private string _curCriteriaID;		// Holds the curently loaded curCriteriaID

		private DataManager dataManager; 


		private ArrayList lastRndSetGenerated = null;				// Holds the last generated/loaded set(s)
		private SetArguments setArgsForLastGeneratedSet = null;		// The setArgs for the sets above
		private SetArguments setArgsForLastGeneratedSample = null;	// The setArgs for the last generated/loaded sample

		CriteriaFormState curFormState;
		CriteriaFormState formStateForCleanCriteria;
		private bool _criteriaClean = true;
		private bool criteriaHasBeenSaved = false;

		private bool _criteriaDataLoaded = false;	// Set to true after xml criteria file has been read into the dataset


		ViewSummary viewSummary;


		#endregion

		#region CONST

		private const int formWidth = 406;
        private const int formHeight = 431; // setting explicitly because of apparent vs2008 designer bug that keeps shrinking window size
		private const int formWidthExpanded = 652;
		private const string aboutBoxMesg = "";
		private const string formBaseText = "RandomRat v0.8.0";
		private const bool debuging = true;

		#endregion


		#region WINVARS

		private System.Windows.Forms.ListBox listBox1;
		private System.Windows.Forms.MainMenu mainMenu1;
		private System.Windows.Forms.MenuItem menFile;
		private System.Windows.Forms.MenuItem menFile_Exit;
		private System.Windows.Forms.MenuItem menFile_Print;
		private System.Windows.Forms.MenuItem menHelp;
		private System.Windows.Forms.MenuItem menHelp_About;
		private System.Windows.Forms.TextBox textBox1;
		private System.Windows.Forms.TextBox textBox2;
		private System.Windows.Forms.TextBox textBox3;
		private System.Windows.Forms.TextBox textBox4;
		private System.Windows.Forms.Button butTest;
		private System.Windows.Forms.Button butGenSample;
		private System.Windows.Forms.TextBox txtTimeTaken;
		private System.Windows.Forms.StatusBar statusBar1;
		private System.Windows.Forms.StatusBarPanel statusBarPanel1;
		private System.Windows.Forms.StatusBarPanel statusBarPanel2;
		private System.Windows.Forms.StatusBarPanel statusBarPanel3;
		private System.Windows.Forms.Timer timer1;
		private System.Windows.Forms.MenuItem menView;
		private System.Windows.Forms.TextBox textBox5;
		private System.Windows.Forms.TextBox textBox6;
		private System.Windows.Forms.RichTextBox richTextStats;
		private System.Windows.Forms.MenuItem menView_Details;
		private System.Windows.Forms.MenuItem menFiel_PrintPreview;
		private System.Windows.Forms.MenuItem menuItem1;
		private System.Windows.Forms.MenuItem menuItem4;
		private System.Windows.Forms.MenuItem menuItem18;
		private System.Windows.Forms.MenuItem menFile_SetCriteriaWizard;
		private System.Windows.Forms.MenuItem menFile_Criteria;
		private System.Windows.Forms.MenuItem menFile_Criteria_Load;
		private System.Windows.Forms.MenuItem menFile_Criteria_Save;
		private System.Windows.Forms.MenuItem menFile_Criteria_SaveAs;
		private System.Windows.Forms.GroupBox Detailes;
		private System.Windows.Forms.Label label3;
		private System.Windows.Forms.Label label4;
		private System.Windows.Forms.Label label5;
		private System.Windows.Forms.Label label6;
		private System.Windows.Forms.Label label7;
		private System.Windows.Forms.Label label8;
		private System.Windows.Forms.Label label9;
		private System.Windows.Forms.MenuItem menFile_Rename;
		private System.Windows.Forms.MenuItem menuItem9;
		private System.Windows.Forms.MenuItem menFile_Criteria_New;
		private System.Windows.Forms.MenuItem menFile_CurSample;
		private System.Windows.Forms.MenuItem menFile_CurSample_SaveAs;
		private System.Windows.Forms.MenuItem menFile_CurSample_CopyToClip;
		private System.Windows.Forms.MenuItem menFile_CurSets_SaveAs;
		private System.Windows.Forms.MenuItem menFile_CurSets_CopyToClip;
		private System.Windows.Forms.MenuItem menView_QuickStart;
		private System.Windows.Forms.MenuItem menuItem6;
		private RandomRat.TypeControl typeControl1;
		private RandomRat.OptionsControl optionsControl1;
		private System.Windows.Forms.MenuItem menView_Summary;
		private System.Windows.Forms.MenuItem menView_SetsViewer;
		private System.Windows.Forms.MenuItem menView_Options;
		private System.Windows.Forms.MenuItem menFile_CurSets;
		private System.Windows.Forms.MenuItem menFile_Generate;
		private System.ComponentModel.IContainer components;

		#endregion

		// The Constructor!
		public Form1()	{
			// Load data first
			dataManager = new DataManager();
			dataManager.ReadInCriteriaData();


			// OK, now start
			InitializeComponent();
			
			rndSetGen = new RandomSetGenerator();
			
			// Hook up change handeler
            optionsControl1.Change += new ChangeEventHandler(this.changeHandaler);
			typeControl1.Change += new ChangeEventHandler(this.changeHandaler);

			this.Text = formBaseText;

			
			
			#region Handeler hookup

			rndSetGen.CleanUp += new ProgressEventHandler(this.progressHandler);
			rndSetGen.PatternSwapping += new ProgressEventHandler(this.progressHandler);
			rndSetGen.SetGeneration += new ProgressEventHandler(this.progressHandler);
			rndSetGen.SuccessionSwapping += new ProgressEventHandler(this.progressHandler);

			rndSetGen.ViolationGroupingIndexesExhausted += new ProgressEventHandler(this.indexesExhaustedHandler);
			rndSetGen.SetTypeIndexesExhausted += new ProgressEventHandler(this.indexesExhaustedHandler);


			rndSetGen.CleanUp += new ProgressEventHandler(this.progressHandler2);
			rndSetGen.PatternSwapping += new ProgressEventHandler(this.progressHandler2);
			//rndSetGen.SetGeneration += new ProgressEventHandler(this.progressHandler2);
			rndSetGen.SuccessionSwapping += new ProgressEventHandler(this.progressHandler2);
			rndSetGen.ViolationGroupingIndexesExhausted += new ProgressEventHandler(this.progressHandler2);
			rndSetGen.SetTypeIndexesExhausted += new ProgressEventHandler(this.progressHandler2);

			#endregion

		}



		#region Criteria

		// Property for curent criteria (when sets, also sets viusal components)
		private string curCriteriaID {
			get { return _curCriteriaID; }
			set { 
				_curCriteriaID = value;
				updateFormText();
				updateCleanStatus();
			}
		}

		public string CurCriteriaID {
			get { return _curCriteriaID; }
		}
		public bool CurCriteriaHasBeenSaved {
			get { return criteriaHasBeenSaved; }
		}

		private void updateFormText() {
			StringBuilder sb = new StringBuilder();
			sb.Append(formBaseText);
			if (_curCriteriaID != null && _curCriteriaID != "") {
				sb.Append(" - " + _curCriteriaID);

				if (!_criteriaClean) {
					sb.Append("*");
				}
			}

			this.Text = sb.ToString();
		}


		#region All things dealing with Clean/Unclean, ask user if they want to save, etc.

		private bool canProceedWith_NewLoadClose() {
			if (_curCriteriaID == null) {
				return true;
			}
			
			bool proceed = true;

			updateCleanStatus();

			if (!criteriaClean) {
				string msg = "Criteria '" + curCriteriaID + "' has changed." + "\n\n" +
					"Do you want to save the changes?";

				DialogResult result = MessageBox.Show(this, msg, "RandomRat", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning);
				
				if (result == DialogResult.Yes) {
					saveCriteria(false);
				} else if (result == DialogResult.Cancel) {
					proceed = false;
				}
			}

			return proceed;
		}


		private bool criteriaClean {
			get { return _criteriaClean; }
			set {
				if (_criteriaClean != value) {
					_criteriaClean = value;
					updateFormText();			
				}
			}
		}

		private void updateCleanStatus() {
			curFormState = getFormState();

			if (viewSummary != null && viewSummary.Visible) {
				viewSummary.SetFormState(curFormState);
			}

			if (formStateForCleanCriteria != null && 
				(CriteriaFormState.IsBlank(curFormState) ||
				formStateForCleanCriteria.ToString().CompareTo(curFormState.ToString()) == 0)) {
				this.criteriaClean = true;

			} else {	
				this.criteriaClean = false;
			}
		}

		private void setCleanState() {
			formStateForCleanCriteria = getFormState();
			curFormState = formStateForCleanCriteria;
			criteriaClean = true;
		}
		
		private void setCleanState(CriteriaFormState formState) {
			formStateForCleanCriteria = formState;
			
			if (formState != null) {
				criteriaClean = true;
			} else {
				criteriaClean = false;
			}
		}


		#endregion

		#region New (Wizard) Critiera
		
		private void showNewCriteriaWizardDialog() {  
			if (!canProceedWith_NewLoadClose()) {			
				return;
			}
			
			CriteriaWizard wizard = new CriteriaWizard();
			wizard.ShowDialog();
			if (wizard.DialogResult == DialogResult.OK) {
				CriteriaFormState formState = wizard.Criteria;

				this.curCriteriaID = formState.CriteriaID;

				optionsControl1.LoadSettings(formState);
				typeControl1.LoadTypes(formState);

				clearAndReadyForm();
				setCleanState(null);

				criteriaHasBeenSaved = false; // Forces SaveAs diolog to come up (and other esenshal functions)
			}
		}

		private void newCriteria() {
			if (!canProceedWith_NewLoadClose()) {			
				return;
			}

			this.curCriteriaID = "Untitled Criteria";
			
			// clear controls
			optionsControl1.ClearSettings();
			typeControl1.ClearTypes();
			
			clearAndReadyForm();
			setCleanState();

			criteriaHasBeenSaved = false; // Forces SaveAs diolog to come up (and other esenshal functions)
		}


		#endregion

		#region Load / Save / Rename critiera (With diologs)

		private void loadCriteria() {
			if (canProceedWith_NewLoadClose() && isCriteriaDataLoaded()) {

				CriteriaSelector criteriaSelector = new CriteriaSelector(dataManager, this);
				
				criteriaSelector.ShowDialog();

				if (criteriaSelector.DialogResult == DialogResult.OK) {	
					curCriteriaID = criteriaSelector.SelectedCritieriaID;
			
					// ready form
					optionsControl1.ClearErrors();
					typeControl1.ClearErrors();
						
					clearAndReadyForm();



					// Get formState, load into controls
					this.formStateForCleanCriteria = dataManager.GetCriteriaFormState(curCriteriaID);
					optionsControl1.LoadSettings(formStateForCleanCriteria);
					typeControl1.LoadTypes(formStateForCleanCriteria);
					
					// Has been saved
					criteriaHasBeenSaved = true;
					
					setCleanState();

				}
				criteriaSelector.Dispose();

			}
		}


		private void saveCriteria(bool saveAs) {
			if (!isCriteriaDataLoaded()) {
				return;
			}
			
			CriteriaName criteriaName;

			if (saveAs || curCriteriaID == null || !criteriaHasBeenSaved) {
				if (curCriteriaID != null) {
					criteriaName = new CriteriaName(dataManager.CriteriaDataSet, curCriteriaID, CriteriaNameDialogType.SaveAs);
				} else {
					criteriaName = new CriteriaName(dataManager.CriteriaDataSet, CriteriaNameDialogType.SaveAs);
				}
				
				criteriaName.ShowDialog(this);

				if (criteriaName.DialogResult == DialogResult.OK) {
					curCriteriaID = criteriaName.CriteriaID;
					dataManager.SaveCriteria(curCriteriaID, this.getFormState());

					// Set curent state and criteria as clean
					setCleanState();
					criteriaHasBeenSaved = true;
				}

			} else {
				// Critiera is already named (from a previous save or load): just save.
				dataManager.SaveCriteria(curCriteriaID, this.getFormState());
				setCleanState();
				criteriaHasBeenSaved = true;
			}
		}


		private void renameCriteria() {
			CriteriaName criteriaName = new CriteriaName(dataManager.CriteriaDataSet, 
				this.curCriteriaID, 
				CriteriaNameDialogType.Rename);
			
			if (criteriaName.ShowDialog(this) == DialogResult.OK) {
				dataManager.RenameCriteria(this.curCriteriaID, criteriaName.CriteriaID);

				// Update form
				this.curCriteriaID = criteriaName.CriteriaID;
			}
			criteriaName.Dispose();
		}
		public void RenameCriteria(string newCriteriaID) {
			dataManager.RenameCriteria(this.curCriteriaID, newCriteriaID);

			// Update form
			this.curCriteriaID = newCriteriaID;
		}
		
		
		#endregion

		private CriteriaFormState getFormState() {
			CriteriaFormState formState = new CriteriaFormState();
			
			formState.CriteriaID = curCriteriaID;
			
			optionsControl1.FillFormState(ref formState);
			typeControl1.FillFormState(ref formState);
			if (criteriaHasBeenSaved) {
				formState.Sets = dataManager.GetSets(curCriteriaID);
			} else {
				formState.Sets = sets;
			}

			return formState;
		}


		private void clearAndReadyForm() {
			sets = "";
			
			// Set status bar to ready
			setStatusBarReadyState();

			// Clear detailes info
			clearDetails();

			// Clear sample List
			listBox1.Items.Clear();

			lastRndSetGenerated = null;				// Holds the last generated/loaded set(s)
			setArgsForLastGeneratedSet = null;		// The setArgs for the sets above
			setArgsForLastGeneratedSample = null;
		}

		
		#endregion






		#region SAVING SETS

		private void menFile_CurSets_CopyToClip_Click(object sender, System.EventArgs e) {

			DataManager.CopySetsToClipboard(lastRndSetGenerated, setArgsForLastGeneratedSet);
			//CopySetsToClipboard

//			if (lastRndSetGenerated.Count > 0) {
//				
//				StringBuilder sb = new StringBuilder();
//				sb.Append(setArgsForLastGeneratedSet.ToString() + "\n");
//				
//				for (int slot = 0; slot < setArgsForLastGeneratedSet.Slots; slot++) {
//					for (int setID = 0; setID < lastRndSetGenerated.Count; setID++) {
//						if (setID == 0)	{
//							sb.Append(((string[])lastRndSetGenerated[setID])[slot]);
//						} else {
//							sb.Append("\t" + ((string[])lastRndSetGenerated[setID])[slot]);
//						}
//					}
//					if (slot + 1 < setArgsForLastGeneratedSet.Slots) {
//						sb.Append("\n");
//					}
//				}
//				
//				Clipboard.SetDataObject(sb.ToString(), true);
//			}
		}

		
		private void menFile_CurSample_CopyToClip_Click(object sender, System.EventArgs e) {
			if (listBox1.Items.Count > 0) {

				ArrayList rndSet = new ArrayList(1);
			
				string[] sampleSet = new string[listBox1.Items.Count];
				for (int i = 0; i < sampleSet.Length; i++) {
					sampleSet[i] = (string)listBox1.Items[i];
				}

				rndSet.Add(sampleSet);
			
				DataManager.CopySetsToClipboard(rndSet, setArgsForLastGeneratedSample);
			}
			
//			if (listBox1.Items.Count > 0) {
//			
//				StringBuilder sb = new StringBuilder();
//			
//				sb.Append(setArgsForLastGeneratedSample.ToString() + "\n");
//
//				sb.Append(listBox1.Items[0].ToString());
//				for (int i = 1; i < listBox1.Items.Count; i++) {
//					sb.Append("\n" + listBox1.Items[i].ToString());
//				}	
//
//				Clipboard.SetDataObject(sb.ToString(), true);
//			}
		
		}

		
		private void menFile_CurSample_SaveAs_Click(object sender, System.EventArgs e) {
			if (listBox1.Items.Count > 0) {
				ArrayList rndSets = new ArrayList(1);
				
				string[] items = new string[listBox1.Items.Count];
				for (int i = 0 ; i < items.Length; i++) {
					items[i] = (string)listBox1.Items[i];
				}

				rndSets.Add(items);

				DataManager.SaveSetsToFile(rndSets, curFormState, SetsFileType.Sample);		
			}
		}


		private void menFile_CurSample_Load_Click(object sender, System.EventArgs e) {
			// Show open diolog
			OpenFileDialog openFileDialog1 = new OpenFileDialog();

			//openFileDialog1.InitialDirectory = "c:\\" ;
			openFileDialog1.Filter = "RandomRat sample files (*.samp)|*.samp";
			openFileDialog1.FilterIndex = 1;
			openFileDialog1.RestoreDirectory = true ;

			if(openFileDialog1.ShowDialog() == DialogResult.OK) {
				
				RndSetsDataSet rndSetsDataSet = new RndSetsDataSet();
				//dataGrid1.DataSource = rndSetsDataSet;
				
				// Read in data
				rndSetsDataSet.ReadXml(openFileDialog1.FileName);

				// Hook up relationship
				rndSetsDataSet.Relations.Add(rndSetsDataSet.Tables["Criteria"].Columns["CriteriaID"], 
											 rndSetsDataSet.Tables["Sets"].Columns["CriteriaID"]);
				
				rndSetsDataSet.Relations.Add(rndSetsDataSet.Tables["Sets"].Columns["SetID"], 
											 rndSetsDataSet.Tables["SetItems"].Columns["SetID"]);

				// Navigate to first row in Criteria
				// Done

				// Clear sample ListBox
				listBox1.Items.Clear();

				// Iterate over the Set table, populating the listBox
				DataTable setItems = rndSetsDataSet.Tables["SetItems"];
				foreach (DataRow setRow in setItems.Rows) {
					listBox1.Items.Add(setRow["Type"]);
				}
				
				// Generate SetArguments and assine to curentlyGeneratedSampleSetArgs

				// Generate SetArguments and assine to curentlyGeneratedSampleSetArgs
				DataTable criteria = rndSetsDataSet.Tables["Criteria"];
				DataTable typesTable = rndSetsDataSet.Tables["Types"];
				DataTable patternsTable = rndSetsDataSet.Tables["Patterns"];

				int slots = (int)criteria.Rows[0]["Slots"];
				
				ArrayList typesAL = new ArrayList();
				foreach (DataRow typeRow in typesTable.Rows) {
					typesAL.Add(typeRow["Type"]);
				}		
				
				string[] types = (string[])typesAL.ToArray(typeof(string));

				int successionTol = -1;
				ArrayList rulesAL = new ArrayList();
				foreach (DataRow ruleRow in patternsTable.Rows) {
					if ((int)ruleRow["Grouping"] == 1) {
						successionTol = (int)ruleRow["Tolerance"];
					} else {
						rulesAL.Add(new int[2] {(int)ruleRow["Grouping"], (int)ruleRow["Tolerance"]});
					}
				}

				setArgsForLastGeneratedSample = new SetArguments(slots, types, successionTol);
				setArgsForLastGeneratedSample.patternRules = (int[][])rulesAL.ToArray(typeof(int[]));
					setArgsForLastGeneratedSample.forceEqualTypes = (bool)criteria.Rows[0]["EqualTypes"];

			}

		}

		
		private void menFile_CurSets_SaveAs_Click(object sender, System.EventArgs e) {
			if (lastRndSetGenerated != null && lastRndSetGenerated.Count > 0) {
				DataManager.SaveSetsToFile(lastRndSetGenerated, curFormState, SetsFileType.Multiple);
			}
		}

		
		private void menFile_CurSets_Load_Click(object sender, System.EventArgs e) {
			// Show open diolog
			OpenFileDialog openFileDialog1 = new OpenFileDialog();

			//openFileDialog1.InitialDirectory = "c:\\" ;
			openFileDialog1.Filter = "RandomRat sets files (*.sets)|*.sets";
			openFileDialog1.FilterIndex = 1;
			openFileDialog1.RestoreDirectory = true ;

			if(openFileDialog1.ShowDialog() == DialogResult.OK) {
				
				RndSetsDataSet rndSetsDataSet = new RndSetsDataSet();
				//dataGrid1.DataSource = rndSetsDataSet;
				
				// Read in data
				rndSetsDataSet.ReadXml(openFileDialog1.FileName);

				// Hook up relationship
				rndSetsDataSet.Relations.Add(rndSetsDataSet.Tables["Criteria"].Columns["CriteriaID"], 
											 rndSetsDataSet.Tables["Sets"].Columns["CriteriaID"]);

				rndSetsDataSet.Relations.Add(rndSetsDataSet.Tables["Criteria"].Columns["CriteriaID"], 
											 rndSetsDataSet.Tables["Types"].Columns["CriteriaID"]);
				rndSetsDataSet.Relations.Add(rndSetsDataSet.Tables["Criteria"].Columns["CriteriaID"], 
											 rndSetsDataSet.Tables["Patterns"].Columns["CriteriaID"]);
				
				rndSetsDataSet.Relations.Add(rndSetsDataSet.Tables["Sets"].Columns["SetID"], 
											 rndSetsDataSet.Tables["SetItems"].Columns["SetID"]);



				// Navigate to first row in Criteria
				// Done

				
				if (lastRndSetGenerated == null) lastRndSetGenerated = new ArrayList();
				lastRndSetGenerated.Clear();

				ArrayList setItemsAL = new ArrayList();

				DataTable sets = rndSetsDataSet.Tables["Sets"];
				foreach (DataRow setRow in sets.Rows) {
					setItemsAL.Clear();

					// Iterate over SetItems
					DataTable setItems = rndSetsDataSet.Tables["SetItems"];
					foreach (DataRow setItemRow in setItems.Rows) {
						if ((int)setItemRow["SetID"] == (int)setRow["SetID"]) {
							setItemsAL.Add(setItemRow["Type"]);
						}
					}
					
                    lastRndSetGenerated.Add(setItemsAL.ToArray(typeof(string)));		
				}

				// Generate SetArguments and assine to curentlyGeneratedSampleSetArgs
				DataTable criteria = rndSetsDataSet.Tables["Criteria"];
				DataTable typesTable = rndSetsDataSet.Tables["Types"];
				DataTable patternsTable = rndSetsDataSet.Tables["Patterns"];

				int slots = (int)criteria.Rows[0]["Slots"];
				
				ArrayList typesAL = new ArrayList();
				foreach (DataRow typeRow in typesTable.Rows) {
					typesAL.Add(typeRow["Type"]);
				}		
				
				string[] types = (string[])typesAL.ToArray(typeof(string));

				int successionTol = -1;
				ArrayList rulesAL = new ArrayList();
				foreach (DataRow ruleRow in patternsTable.Rows) {
					if ((int)ruleRow["Grouping"] == 1) {
						successionTol = (int)ruleRow["Tolerance"];
					} else {
						rulesAL.Add(new int[2] {(int)ruleRow["Grouping"], (int)ruleRow["Tolerance"]});
					}
				}

				setArgsForLastGeneratedSet = new SetArguments(slots, types, successionTol);
				setArgsForLastGeneratedSet.patternRules = (int[][])rulesAL.ToArray(typeof(int[]));
				setArgsForLastGeneratedSet.forceEqualTypes = (bool)criteria.Rows[0]["EqualTypes"];
				
				
//				SetsViewer setView = new SetsViewer(rndSetsDataSet, setArgsForLastGeneratedSet);
//				setView.ShowDialog();
//				setView.Dispose();
			}
		}

		


		

		#endregion

		private void showQuickStartDialog() {
			QuickStart quickStart;
			if (criteriaHasBeenSaved) {
				quickStart = new QuickStart(dataManager, this);
			} else {
				quickStart = new QuickStart(dataManager, null);
			}

			quickStart.ShowDialog(this);
			QuickStartAction action = quickStart.Action;
			quickStart.Dispose();
				
			this.Focus();

			if (action == QuickStartAction.NewCriteria) {
				newCriteria();

			} else if (action == QuickStartAction.NewCriteriaWizard) {
				showNewCriteriaWizardDialog();

			} else if (action == QuickStartAction.ExitRandomRat) {
				this.Close();

			} else if (action == QuickStartAction.LoadFromFile) {

			}
		}



		// TEST BUTON
		private void butTest_Click(object sender, System.EventArgs e) {
			
		}

		#region TEMP stuff I dont have to deal with right now

		
		#region Generating sample set + status bar

		// Generates and displayes valid set in listbox || Aborts generation
		private void butGenSample_Click(object sender, System.EventArgs e) {
			if (((Button)sender).Text == "Generate Sample" && (workerThread == null || !workerThread.IsAlive)) {

				if (isInputValid()) {
					richTextStats.Clear();
					workerThread = new Thread(new ThreadStart(this.genSampleList));

                   
                    
                    workerThread.Start();

                    

					// This timer will change the buttons text to "Abort" in a short time
					// This previents the flashing of abort when sets are generated very
					// quickly (most of the time).
					timer1.Enabled = true;
				}

			} else if (((Button)sender).Text == "Abort") {
								
				//listBox1.Items.Clear();
				if (workerThread.IsAlive) {
					workerThread.Abort();
				} else {
					Console.WriteLine("Something is wrong");
				}

				((Button)sender).Text = "Generate Sample";
				statusBar1.Panels[0].Text = "  process aborted";
				statusBar1.Panels[1].Text = "";
				statusBar1.Panels[2].Text = "";
			}
		}


        SetArguments lastSetArgs;
        private void preGenSampleUIWork() {
            statusBar1.Panels[2].Text = "";

            textBox1.Text = "0";
            textBox2.Text = "0";
            textBox3.Text = "0";
            textBox4.Text = "0";
            txtTimeTaken.Text = "";

            textBox5.Text = "";
            textBox6.Text = "";



            lastGenSampleList_startTime = DateTime.Now;

            lastSetArgs = getUserInputtedArguments();

        }

        private void postGenSampleUIWork()
        {
            string[] rndSet = lastGenSampleList_rndSet;

            // Listbox wont work if user is alowed to terminate thread which updating it
            timer1.Enabled = false; // Bad state if we forget to turn this timer off!!
            butGenSample.Text = "Generate Sample";

            if (rndSet.Length >= 10000)
            {
                statusBar1.Panels[0].Text = "  filling listbox . . .";
                statusBar1.Panels[1].Text = "";
            }


            listBox1.Items.Clear();
            listBox1.Items.AddRange(rndSet);  // This can take an ungodly amount of time


            TimeSpan elapsed = DateTime.Now - lastGenSampleList_startTime;
            statusBar1.Panels[0].Text = "  time taken";
            statusBar1.Panels[1].Text = "  " + Math.Round(elapsed.TotalSeconds, 2).ToString() + "s";

            txtTimeTaken.Text = elapsed.TotalSeconds.ToString();

            setArgsForLastGeneratedSample = lastSetArgs;
        }

        string[] lastGenSampleList_rndSet;
        DateTime lastGenSampleList_startTime;

		// Generates sample valid set and dysplays it in the form's listbox
		private void genSampleList() {

            this.Invoke(new UIWork(preGenSampleUIWork));

            lastGenSampleList_rndSet = rndSetGen.GetValidList(lastSetArgs);

            this.Invoke(new UIWork(postGenSampleUIWork));
		}



		// Waits a bit befor alowing Abort (eliminates flashes when sample taks a short time to gen)
		private void timer1_Tick(object sender, System.EventArgs e) {
			if (workerThread.IsAlive) {
				butGenSample.Text = "Abort";
			}
			((System.Windows.Forms.Timer)sender).Enabled = false;
		}

		

		#region PROGRESS HANDELERS

		Process curProcess = Process.SuccessionSwapping;

		int curSuccessionSwappingCnt = 0;
		int groupingViolation_SUC = 0;
		int setTypeViolation_SUC = 0;

		int curPatternSwappingCnt = 0;
		int groupingViolation_PAT = 0;
		int setTypeViolation_PAT = 0;

		int totalLoops = 0;

        private delegate void ProgressHandler(object sender, ProgressEventArgs e);

		// Wow, all this progress handeling is messy, I really dont know what it does
		private void progressHandler2(object sender, ProgressEventArgs e) {

            if (InvokeRequired)
            {
                this.Invoke(new ProgressHandler(progressHandler2), sender, e);
                return;
            }

			if (e.CurProcess == Process.CleanUp && e.WorkCompleted == 0) {
				richTextStats.Clear();
			}
			
			if (curProcess != e.CurProcess && e.CurProcess == Process.SuccessionSwapping ||
				e.CurProcess == Process.PatternSwapping) {
				curProcess = e.CurProcess;
			}
			
			
			if (e.CurProcess == Process.CleanUp && e.WorkCompleted != 0) {
				StringBuilder sb = new StringBuilder();

				sb.Append("Succession\t" + curSuccessionSwappingCnt.ToString());
				sb.Append("  FE(" + groupingViolation_SUC.ToString() + ", " + 
					setTypeViolation_SUC.ToString() + ")\n");

				sb.Append("Pattern\t\t" + curPatternSwappingCnt.ToString());
				sb.Append("  FE(" + groupingViolation_PAT.ToString() + ", " + 
					setTypeViolation_PAT.ToString() + ") \n");

				richTextStats.AppendText(sb.ToString());

				curSuccessionSwappingCnt = 0;
				groupingViolation_SUC = 0;
				setTypeViolation_SUC = 0;

				curPatternSwappingCnt = 0;
				groupingViolation_PAT = 0;
				setTypeViolation_PAT = 0;
			} 
			
			if (e.CurProcess == Process.CleanUp) {
				totalLoops = e.WorkCompleted;
			
			} else if (e.CurProcess == Process.SuccessionSwapping) {
				curSuccessionSwappingCnt = e.WorkCompleted;

			} else if (e.CurProcess == Process.PatternSwapping) {
				curPatternSwappingCnt = e.WorkCompleted;			

			}else if (e.CurProcess == Process.ViolationGroupingIndexesExhausted) {
				if (curProcess == Process.SuccessionSwapping) {
					groupingViolation_SUC = e.WorkCompleted;
				} else if (curProcess == Process.PatternSwapping) {
					groupingViolation_PAT = e.WorkCompleted;
				}

			} else if (e.CurProcess == Process.SetTypeIndexesExhausted) {
				if (curProcess == Process.SuccessionSwapping) {
					setTypeViolation_SUC = e.WorkCompleted;
				} else if (curProcess == Process.PatternSwapping) {
					setTypeViolation_PAT = e.WorkCompleted;
				}
			}

		}
		
		
		// Handles progress updates
		private void progressHandler(object sender, ProgressEventArgs e) {

            if (InvokeRequired)
            {
                this.Invoke(new ProgressHandler(progressHandler), sender, e);
                return;
            }

			if (e.CurProcess == Process.CleanUp) {
				textBox1.Text = e.WorkCompleted.ToString();
				
				if (e.WorkCompleted > 5) {
					statusBar1.Panels[2].Text = "  " + e.WorkCompleted.ToString();
				}
			
			} else if (e.CurProcess == Process.PatternSwapping || e.CurProcess == Process.PatternCorrection) {
				textBox3.Text = e.WorkCompleted.ToString();
				
				if (e.WorkCompleted > 30) {
					string processText = "";
					
					if (e.CurProcess == Process.PatternSwapping) {
						processText = "  pattern swap";
					} else if (e.CurProcess == Process.PatternCorrection) {
						processText = "  pattern correction";
					}
					
					setStatusBarText(processText, e.WorkCompleted.ToString());
				}

			} else if (e.CurProcess == Process.SetGeneration) {
				// IDEA: Could modifiy eventArgs to include setArgs info and then
				// decide what imcrmentation to show Process.SetGeneration.
				// The smaller the set, the smaller the increment and vica versa
				
				if (e.SetArgs.Slots >= 20000 && e.WorkCompleted % 100 == 0 ||
					e.SetArgs.Slots >= 500000 && e.WorkCompleted % 5 == 0) {


					textBox4.Text = e.WorkCompleted.ToString();
					
					if (e.WorkCompleted > 30 || e.SetArgs.Slots >= 50000) {
						string processText = "  generating raw set";
						if (statusBar1.Panels[0].Text != processText)
							statusBar1.Panels[0].Text = processText;
				
						statusBar1.Panels[1].Text = "  " + e.WorkCompleted + " / " + e.SetArgs.Slots.ToString();
					}
					
					//setStatusBarText(processText, e.WorkCompleted.ToString()); 4990
				} 
			
			} else if (e.CurProcess == Process.SuccessionSwapping || e.CurProcess == Process.SuccessionCorrection) {
				textBox2.Text = e.WorkCompleted.ToString();
				
				if (e.WorkCompleted > 30) {
					string processText = "";

					if (e.CurProcess == Process.SuccessionSwapping) {
						processText = "  succession swap";
					} else if (e.CurProcess == Process.SuccessionCorrection) {
						processText = "  succession correction";
					}
					
					setStatusBarText(processText, e.WorkCompleted.ToString());
				}
			}
		}

		private void indexesExhaustedHandler(object sender, ProgressEventArgs e) {
			if (e.CurProcess == Process.ViolationGroupingIndexesExhausted) {
				textBox5.Text = e.WorkCompleted.ToString();
			} else if (e.CurProcess == Process.SetTypeIndexesExhausted) {
				textBox6.Text = e.WorkCompleted.ToString();
			}

			if (e.WorkCompleted > 30 && statusBar1.Panels[0].Text != "  Generating set . . ." &&
				!this.getUserInputtedArguments().forceEqualTypes) {
				
				statusBar1.Panels[0].Text = "  Generating set . . .";
				statusBar1.Panels[1].Text = "";
			}
		}


		// Clear detales
		private void clearDetails() {
			richTextStats.Clear();
			
			textBox1.Text = "";
			textBox2.Text = "";
			textBox3.Text = "";
			textBox4.Text = "";
			textBox5.Text = "";
			textBox6.Text = "";

			txtTimeTaken.Text = "";
		}

		#endregion

		// Used to set curent prosses and work compleated on it
		// only updating the curent prosses part as needed (to eliminate flashing)
		private void setStatusBarText(string processText, string workCompleated) {
			if (statusBar1.Panels[0].Text != processText)
				statusBar1.Panels[0].Text = processText;
				
			statusBar1.Panels[1].Text = "  " + workCompleated;
		}

		private void setStatusBarReadyState() {
			statusBar1.Panels[0].Text = "  Ready";
			statusBar1.Panels[1].Text = "";
			statusBar1.Panels[2].Text = "";
		}

		
		#endregion


		#region PRINTING

		private string sets = "";	// Holds sets (to print) for unsaved criteria

		// Entery function for printing hardcopies
		private void showPrintDiolog(bool printPreview) {
			if (isInputValid()) {
				SetArguments setArgs = getUserInputtedArguments();
				int radioSelection = getPrintOptionsGuess();
				
				PrintSets printSets;
				if (criteriaHasBeenSaved) {
					printSets = new PrintSets(setArgs, printPreview, dataManager.GetSets(curCriteriaID), radioSelection, 
						listBox1, setArgsForLastGeneratedSample, 
						lastRndSetGenerated, setArgsForLastGeneratedSet);
				} else {
					printSets = new PrintSets(setArgs, printPreview, sets, radioSelection, 
						listBox1, setArgsForLastGeneratedSample, 
						lastRndSetGenerated, setArgsForLastGeneratedSet);
				}
				
				
				printSets.ShowDialog();

				if (printSets.DialogResult == DialogResult.OK) {
					if (printSets.Sets != "") {

						curFormState.Sets = printSets.Sets;

						if (criteriaHasBeenSaved) {
							dataManager.SaveSets(this.curCriteriaID, printSets.Sets);
						} else {
							sets = printSets.Sets;
						}
					}

					if (printSets.RndSetsGenerated != null) {
						lastRndSetGenerated = printSets.RndSetsGenerated;
						setArgsForLastGeneratedSet = setArgs;
					}
				}
				
				printSets.Dispose();
				return;
			}
		}

		// Guesses at what the user wants to print (a previously generated set
		// or a newly generated one)
		public int getPrintOptionsGuess() {
			SetArguments curSetArgs = getUserInputtedArguments();
			if (lastRndSetGenerated != null && setArgsForLastGeneratedSet != null &&
				curSetArgs.ToString() == setArgsForLastGeneratedSet.ToString()) {
				return 2;  // Option to use most recently generated set
			} else {
				return 3;  // Option to generate new set
			}
		}


		#endregion


		#region MENUES

		private void menFile_Exit_Click(object sender, System.EventArgs e) {
			this.Close();
		}
		private void menFiel_PrintPreview_Click(object sender, System.EventArgs e) {
			showPrintDiolog(true);
		}
		private void menFile_Print_Click(object sender, System.EventArgs e) {
			showPrintDiolog(false);
		}
		private void menHelp_About_Click(object sender, System.EventArgs e) {
		
			AboutBox aBox = new AboutBox();
			aBox.ShowDialog(this);
			aBox.Dispose();


//			MessageBox.Show(this, "RandomRat is a program for generating random sets that meet specific criteria.\n\n" +
//				"Developed by Mark Samuelson - mas_inc2@hotmail.com\n" +
//				"Copyright 2003 - All rights reserved",
//				"", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}

		#endregion


		#region Form loading/closing with assosheated preosseses

		// Forms load event
		private void Form1_Load(object sender, System.EventArgs e) {
			// Set up form
			this.FormBorderStyle = FormBorderStyle.FixedSingle;
			this.Width = formWidth;
            this.Height = formHeight;

			if (ApplicationSettings.StartupCriteria == StartupCriteriaType.Blank) {
				newCriteria();
			
			} else if (ApplicationSettings.StartupCriteria == StartupCriteriaType.Specified) {
				string criteriaID = ApplicationSettings.SpecifiedCriteria;
				if (dataManager.CriteriaExists(criteriaID)) {
				
					curCriteriaID = criteriaID;
			
					// ready form
					optionsControl1.ClearErrors();
					typeControl1.ClearErrors();
						
					clearAndReadyForm();
			
					// Get formState, load into controls
					this.formStateForCleanCriteria = dataManager.GetCriteriaFormState(curCriteriaID);
					optionsControl1.LoadSettings(formStateForCleanCriteria);
					typeControl1.LoadTypes(formStateForCleanCriteria);

					// Has been saved
					criteriaHasBeenSaved = true;
					
					setCleanState();
				
				} else {
					ApplicationSettings.StartupCriteria = StartupCriteriaType.Blank;
					ApplicationSettings.SpecifiedCriteria = "";
					newCriteria();
				}
			}
		}

		private bool isCriteriaDataLoaded() {
			if (!dataManager.CriteriaDataLoaded) {
				MessageBox.Show(this, "Criteria data is still being loaded." + "\n" +
					"Please wait a moment and then try again.");
				return false;
			}
			return true;
		}

		// Expands form to show or hide detales
		private void menView_Details_Click(object sender, System.EventArgs e) {
			((MenuItem)sender).Checked = !((MenuItem)sender).Checked;
			if (((MenuItem)sender).Checked) {
				this.Width = formWidthExpanded;
			} else {
				this.Width = formWidth;
			}
		}


		// Form closing
		private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
			
			if (canProceedWith_NewLoadClose()) {			
				dataManager.WriteOutCriteriaData();
			} else {
				e.Cancel = true;
			}

			if (workerThread != null && workerThread.IsAlive) {
				workerThread.Abort();
			}
			if (workerThread2 != null && workerThread2.IsAlive) {
				workerThread2.Abort();
			}
		}

		
		#endregion
		


		// Writes sets to a text file [FILE-IO]
		public void WriteSetsAsText(SetArguments setArgs, ArrayList rndSets, string path) {
			try {
				StreamWriter sw = new StreamWriter(path, false);
				foreach (string[] rndSet in rndSets) {
					foreach (string type in rndSet) {
						sw.WriteLine(type);
					}
					sw.WriteLine("");
				}
				sw.Close();
			} catch (Exception e) {
				throw e;
			}
		}
		


		protected override void Dispose( bool disposing ) {
			if( disposing ) {
				if (workerThread != null && workerThread.IsAlive) {
					workerThread.Abort();
				}
				if (workerThread2 != null && workerThread2.IsAlive) {
					workerThread2.Abort();
				}

				if (viewSummary != null) viewSummary.Dispose();

				if (components != null) {
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region UTIL
		#region Windows Form Designer generated code
		private void InitializeComponent() {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.listBox1 = new System.Windows.Forms.ListBox();
            this.butGenSample = new System.Windows.Forms.Button();
            this.butTest = new System.Windows.Forms.Button();
            this.mainMenu1 = new System.Windows.Forms.MainMenu(this.components);
            this.menFile = new System.Windows.Forms.MenuItem();
            this.menFile_SetCriteriaWizard = new System.Windows.Forms.MenuItem();
            this.menFile_Criteria = new System.Windows.Forms.MenuItem();
            this.menFile_Criteria_New = new System.Windows.Forms.MenuItem();
            this.menFile_Criteria_Load = new System.Windows.Forms.MenuItem();
            this.menFile_Criteria_Save = new System.Windows.Forms.MenuItem();
            this.menFile_Criteria_SaveAs = new System.Windows.Forms.MenuItem();
            this.menuItem9 = new System.Windows.Forms.MenuItem();
            this.menFile_Rename = new System.Windows.Forms.MenuItem();
            this.menuItem4 = new System.Windows.Forms.MenuItem();
            this.menFile_Generate = new System.Windows.Forms.MenuItem();
            this.menFile_CurSets = new System.Windows.Forms.MenuItem();
            this.menFile_CurSets_SaveAs = new System.Windows.Forms.MenuItem();
            this.menFile_CurSets_CopyToClip = new System.Windows.Forms.MenuItem();
            this.menFile_CurSample = new System.Windows.Forms.MenuItem();
            this.menFile_CurSample_SaveAs = new System.Windows.Forms.MenuItem();
            this.menFile_CurSample_CopyToClip = new System.Windows.Forms.MenuItem();
            this.menuItem18 = new System.Windows.Forms.MenuItem();
            this.menFiel_PrintPreview = new System.Windows.Forms.MenuItem();
            this.menFile_Print = new System.Windows.Forms.MenuItem();
            this.menuItem1 = new System.Windows.Forms.MenuItem();
            this.menFile_Exit = new System.Windows.Forms.MenuItem();
            this.menView = new System.Windows.Forms.MenuItem();
            this.menView_QuickStart = new System.Windows.Forms.MenuItem();
            this.menView_SetsViewer = new System.Windows.Forms.MenuItem();
            this.menView_Summary = new System.Windows.Forms.MenuItem();
            this.menView_Details = new System.Windows.Forms.MenuItem();
            this.menuItem6 = new System.Windows.Forms.MenuItem();
            this.menView_Options = new System.Windows.Forms.MenuItem();
            this.menHelp = new System.Windows.Forms.MenuItem();
            this.menHelp_About = new System.Windows.Forms.MenuItem();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.textBox2 = new System.Windows.Forms.TextBox();
            this.textBox3 = new System.Windows.Forms.TextBox();
            this.textBox4 = new System.Windows.Forms.TextBox();
            this.txtTimeTaken = new System.Windows.Forms.TextBox();
            this.statusBar1 = new System.Windows.Forms.StatusBar();
            this.statusBarPanel1 = new System.Windows.Forms.StatusBarPanel();
            this.statusBarPanel2 = new System.Windows.Forms.StatusBarPanel();
            this.statusBarPanel3 = new System.Windows.Forms.StatusBarPanel();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.textBox5 = new System.Windows.Forms.TextBox();
            this.textBox6 = new System.Windows.Forms.TextBox();
            this.richTextStats = new System.Windows.Forms.RichTextBox();
            this.Detailes = new System.Windows.Forms.GroupBox();
            this.label9 = new System.Windows.Forms.Label();
            this.label8 = new System.Windows.Forms.Label();
            this.label7 = new System.Windows.Forms.Label();
            this.label6 = new System.Windows.Forms.Label();
            this.label5 = new System.Windows.Forms.Label();
            this.label4 = new System.Windows.Forms.Label();
            this.label3 = new System.Windows.Forms.Label();
            this.optionsControl1 = new RandomRat.OptionsControl();
            this.typeControl1 = new RandomRat.TypeControl();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel2)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel3)).BeginInit();
            this.Detailes.SuspendLayout();
            this.SuspendLayout();
            // 
            // listBox1
            // 
            this.listBox1.Location = new System.Drawing.Point(8, 12);
            this.listBox1.Name = "listBox1";
            this.listBox1.Size = new System.Drawing.Size(120, 316);
            this.listBox1.TabIndex = 13;
            this.listBox1.TabStop = false;
            // 
            // butGenSample
            // 
            this.butGenSample.Location = new System.Drawing.Point(8, 336);
            this.butGenSample.Name = "butGenSample";
            this.butGenSample.Size = new System.Drawing.Size(120, 23);
            this.butGenSample.TabIndex = 2;
            this.butGenSample.Text = "Generate Sample";
            this.butGenSample.Click += new System.EventHandler(this.butGenSample_Click);
            // 
            // butTest
            // 
            this.butTest.Enabled = false;
            this.butTest.Location = new System.Drawing.Point(172, 272);
            this.butTest.Name = "butTest";
            this.butTest.Size = new System.Drawing.Size(48, 23);
            this.butTest.TabIndex = 14;
            this.butTest.TabStop = false;
            this.butTest.Text = "Test";
            this.butTest.Click += new System.EventHandler(this.butTest_Click);
            // 
            // mainMenu1
            // 
            this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menFile,
            this.menView,
            this.menHelp});
            // 
            // menFile
            // 
            this.menFile.Index = 0;
            this.menFile.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menFile_SetCriteriaWizard,
            this.menFile_Criteria,
            this.menuItem4,
            this.menFile_Generate,
            this.menFile_CurSets,
            this.menFile_CurSample,
            this.menuItem18,
            this.menFiel_PrintPreview,
            this.menFile_Print,
            this.menuItem1,
            this.menFile_Exit});
            this.menFile.Text = "&File";
            this.menFile.Popup += new System.EventHandler(this.menFile_Popup);
            // 
            // menFile_SetCriteriaWizard
            // 
            this.menFile_SetCriteriaWizard.Index = 0;
            this.menFile_SetCriteriaWizard.Text = "New Criteria &Wizard";
            this.menFile_SetCriteriaWizard.Click += new System.EventHandler(this.menFile_SetCriteriaWizard_Click);
            // 
            // menFile_Criteria
            // 
            this.menFile_Criteria.Index = 1;
            this.menFile_Criteria.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menFile_Criteria_New,
            this.menFile_Criteria_Load,
            this.menFile_Criteria_Save,
            this.menFile_Criteria_SaveAs,
            this.menuItem9,
            this.menFile_Rename});
            this.menFile_Criteria.Text = "&Criteria";
            this.menFile_Criteria.Popup += new System.EventHandler(this.menFile_Criteria_Popup);
            // 
            // menFile_Criteria_New
            // 
            this.menFile_Criteria_New.Index = 0;
            this.menFile_Criteria_New.Shortcut = System.Windows.Forms.Shortcut.CtrlN;
            this.menFile_Criteria_New.Text = "&New";
            this.menFile_Criteria_New.Click += new System.EventHandler(this.menFile_Criteria_New_Click);
            // 
            // menFile_Criteria_Load
            // 
            this.menFile_Criteria_Load.Index = 1;
            this.menFile_Criteria_Load.Shortcut = System.Windows.Forms.Shortcut.CtrlL;
            this.menFile_Criteria_Load.Text = "&Load";
            this.menFile_Criteria_Load.Click += new System.EventHandler(this.menFile_Criteria_Load_Click);
            // 
            // menFile_Criteria_Save
            // 
            this.menFile_Criteria_Save.Index = 2;
            this.menFile_Criteria_Save.Shortcut = System.Windows.Forms.Shortcut.CtrlS;
            this.menFile_Criteria_Save.Text = "&Save";
            this.menFile_Criteria_Save.Click += new System.EventHandler(this.menFile_Criteria_Save_Click);
            // 
            // menFile_Criteria_SaveAs
            // 
            this.menFile_Criteria_SaveAs.Index = 3;
            this.menFile_Criteria_SaveAs.Text = "Save &As...";
            this.menFile_Criteria_SaveAs.Click += new System.EventHandler(this.menFile_Criteria_SaveAs_Click);
            // 
            // menuItem9
            // 
            this.menuItem9.Index = 4;
            this.menuItem9.Text = "-";
            // 
            // menFile_Rename
            // 
            this.menFile_Rename.Index = 5;
            this.menFile_Rename.Shortcut = System.Windows.Forms.Shortcut.CtrlR;
            this.menFile_Rename.Text = "&Rename";
            this.menFile_Rename.Click += new System.EventHandler(this.menFile_Rename_Click);
            // 
            // menuItem4
            // 
            this.menuItem4.Index = 2;
            this.menuItem4.Text = "-";
            // 
            // menFile_Generate
            // 
            this.menFile_Generate.Index = 3;
            this.menFile_Generate.Shortcut = System.Windows.Forms.Shortcut.CtrlG;
            this.menFile_Generate.Text = "Generate...";
            this.menFile_Generate.Click += new System.EventHandler(this.menFile_Generate_Click);
            // 
            // menFile_CurSets
            // 
            this.menFile_CurSets.Index = 4;
            this.menFile_CurSets.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menFile_CurSets_SaveAs,
            this.menFile_CurSets_CopyToClip});
            this.menFile_CurSets.Text = "Current Sets";
            // 
            // menFile_CurSets_SaveAs
            // 
            this.menFile_CurSets_SaveAs.Index = 0;
            this.menFile_CurSets_SaveAs.Text = "Save As...";
            this.menFile_CurSets_SaveAs.Click += new System.EventHandler(this.menFile_CurSets_SaveAs_Click);
            // 
            // menFile_CurSets_CopyToClip
            // 
            this.menFile_CurSets_CopyToClip.Index = 1;
            this.menFile_CurSets_CopyToClip.Text = "Copy To Clipboard";
            this.menFile_CurSets_CopyToClip.Click += new System.EventHandler(this.menFile_CurSets_CopyToClip_Click);
            // 
            // menFile_CurSample
            // 
            this.menFile_CurSample.Index = 5;
            this.menFile_CurSample.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menFile_CurSample_SaveAs,
            this.menFile_CurSample_CopyToClip});
            this.menFile_CurSample.Text = "Current Sample";
            // 
            // menFile_CurSample_SaveAs
            // 
            this.menFile_CurSample_SaveAs.Index = 0;
            this.menFile_CurSample_SaveAs.Text = "Save As...";
            this.menFile_CurSample_SaveAs.Click += new System.EventHandler(this.menFile_CurSample_SaveAs_Click);
            // 
            // menFile_CurSample_CopyToClip
            // 
            this.menFile_CurSample_CopyToClip.Index = 1;
            this.menFile_CurSample_CopyToClip.Text = "Copy To Clipboard";
            this.menFile_CurSample_CopyToClip.Click += new System.EventHandler(this.menFile_CurSample_CopyToClip_Click);
            // 
            // menuItem18
            // 
            this.menuItem18.Index = 6;
            this.menuItem18.Text = "-";
            // 
            // menFiel_PrintPreview
            // 
            this.menFiel_PrintPreview.Index = 7;
            this.menFiel_PrintPreview.Text = "Print Pre&view";
            this.menFiel_PrintPreview.Click += new System.EventHandler(this.menFiel_PrintPreview_Click);
            // 
            // menFile_Print
            // 
            this.menFile_Print.Index = 8;
            this.menFile_Print.Shortcut = System.Windows.Forms.Shortcut.CtrlP;
            this.menFile_Print.Text = "&Print...";
            this.menFile_Print.Click += new System.EventHandler(this.menFile_Print_Click);
            // 
            // menuItem1
            // 
            this.menuItem1.Index = 9;
            this.menuItem1.Text = "-";
            // 
            // menFile_Exit
            // 
            this.menFile_Exit.Index = 10;
            this.menFile_Exit.Text = "E&xit";
            this.menFile_Exit.Click += new System.EventHandler(this.menFile_Exit_Click);
            // 
            // menView
            // 
            this.menView.Index = 1;
            this.menView.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menView_QuickStart,
            this.menView_SetsViewer,
            this.menView_Summary,
            this.menView_Details,
            this.menuItem6,
            this.menView_Options});
            this.menView.Text = "&View";
            this.menView.Popup += new System.EventHandler(this.menView_Popup);
            // 
            // menView_QuickStart
            // 
            this.menView_QuickStart.Index = 0;
            this.menView_QuickStart.Text = "&Quick Start";
            this.menView_QuickStart.Click += new System.EventHandler(this.menView_QuickStart_Click);
            // 
            // menView_SetsViewer
            // 
            this.menView_SetsViewer.Index = 1;
            this.menView_SetsViewer.Text = "Sets &Viewer";
            this.menView_SetsViewer.Click += new System.EventHandler(this.menView_SetsViewer_Click);
            // 
            // menView_Summary
            // 
            this.menView_Summary.Index = 2;
            this.menView_Summary.Text = "&Summary";
            this.menView_Summary.Click += new System.EventHandler(this.menView_Summary_Click);
            // 
            // menView_Details
            // 
            this.menView_Details.Index = 3;
            this.menView_Details.Text = "&Details";
            this.menView_Details.Click += new System.EventHandler(this.menView_Details_Click);
            // 
            // menuItem6
            // 
            this.menuItem6.Index = 4;
            this.menuItem6.Text = "-";
            // 
            // menView_Options
            // 
            this.menView_Options.Index = 5;
            this.menView_Options.Text = "S&ettings...";
            this.menView_Options.Click += new System.EventHandler(this.menView_Options_Click);
            // 
            // menHelp
            // 
            this.menHelp.Index = 2;
            this.menHelp.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
            this.menHelp_About});
            this.menHelp.Text = "&Help";
            // 
            // menHelp_About
            // 
            this.menHelp_About.Index = 0;
            this.menHelp_About.Text = "&About RandomRat...";
            this.menHelp_About.Click += new System.EventHandler(this.menHelp_About_Click);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(172, 297);
            this.textBox1.Name = "textBox1";
            this.textBox1.ReadOnly = true;
            this.textBox1.Size = new System.Drawing.Size(48, 20);
            this.textBox1.TabIndex = 24;
            this.textBox1.TabStop = false;
            // 
            // textBox2
            // 
            this.textBox2.Location = new System.Drawing.Point(172, 224);
            this.textBox2.Name = "textBox2";
            this.textBox2.ReadOnly = true;
            this.textBox2.Size = new System.Drawing.Size(48, 20);
            this.textBox2.TabIndex = 26;
            this.textBox2.TabStop = false;
            // 
            // textBox3
            // 
            this.textBox3.Location = new System.Drawing.Point(172, 248);
            this.textBox3.Name = "textBox3";
            this.textBox3.ReadOnly = true;
            this.textBox3.Size = new System.Drawing.Size(48, 20);
            this.textBox3.TabIndex = 27;
            this.textBox3.TabStop = false;
            // 
            // textBox4
            // 
            this.textBox4.Location = new System.Drawing.Point(172, 192);
            this.textBox4.Name = "textBox4";
            this.textBox4.ReadOnly = true;
            this.textBox4.Size = new System.Drawing.Size(48, 20);
            this.textBox4.TabIndex = 28;
            this.textBox4.TabStop = false;
            // 
            // txtTimeTaken
            // 
            this.txtTimeTaken.Location = new System.Drawing.Point(172, 321);
            this.txtTimeTaken.Name = "txtTimeTaken";
            this.txtTimeTaken.ReadOnly = true;
            this.txtTimeTaken.Size = new System.Drawing.Size(48, 20);
            this.txtTimeTaken.TabIndex = 29;
            this.txtTimeTaken.TabStop = false;
            // 
            // statusBar1
            // 
            this.statusBar1.Font = new System.Drawing.Font("Microsoft Sans Serif", 6.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.statusBar1.Location = new System.Drawing.Point(0, 364);
            this.statusBar1.Name = "statusBar1";
            this.statusBar1.Panels.AddRange(new System.Windows.Forms.StatusBarPanel[] {
            this.statusBarPanel1,
            this.statusBarPanel2,
            this.statusBarPanel3});
            this.statusBar1.ShowPanels = true;
            this.statusBar1.Size = new System.Drawing.Size(400, 19);
            this.statusBar1.SizingGrip = false;
            this.statusBar1.TabIndex = 30;
            // 
            // statusBarPanel1
            // 
            this.statusBarPanel1.BorderStyle = System.Windows.Forms.StatusBarPanelBorderStyle.Raised;
            this.statusBarPanel1.Name = "statusBarPanel1";
            this.statusBarPanel1.Text = "  Ready";
            this.statusBarPanel1.Width = 130;
            // 
            // statusBarPanel2
            // 
            this.statusBarPanel2.BorderStyle = System.Windows.Forms.StatusBarPanelBorderStyle.Raised;
            this.statusBarPanel2.Name = "statusBarPanel2";
            this.statusBarPanel2.Width = 130;
            // 
            // statusBarPanel3
            // 
            this.statusBarPanel3.BorderStyle = System.Windows.Forms.StatusBarPanelBorderStyle.Raised;
            this.statusBarPanel3.Name = "statusBarPanel3";
            this.statusBarPanel3.Width = 700;
            // 
            // timer1
            // 
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            // 
            // textBox5
            // 
            this.textBox5.Location = new System.Drawing.Point(41, 273);
            this.textBox5.Name = "textBox5";
            this.textBox5.ReadOnly = true;
            this.textBox5.Size = new System.Drawing.Size(47, 20);
            this.textBox5.TabIndex = 32;
            this.textBox5.TabStop = false;
            // 
            // textBox6
            // 
            this.textBox6.Location = new System.Drawing.Point(120, 273);
            this.textBox6.Name = "textBox6";
            this.textBox6.ReadOnly = true;
            this.textBox6.Size = new System.Drawing.Size(48, 20);
            this.textBox6.TabIndex = 33;
            this.textBox6.TabStop = false;
            // 
            // richTextStats
            // 
            this.richTextStats.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
            this.richTextStats.Location = new System.Drawing.Point(14, 22);
            this.richTextStats.Name = "richTextStats";
            this.richTextStats.ReadOnly = true;
            this.richTextStats.Size = new System.Drawing.Size(207, 152);
            this.richTextStats.TabIndex = 36;
            this.richTextStats.TabStop = false;
            this.richTextStats.Text = "";
            this.richTextStats.WordWrap = false;
            // 
            // Detailes
            // 
            this.Detailes.Controls.Add(this.textBox6);
            this.Detailes.Controls.Add(this.label9);
            this.Detailes.Controls.Add(this.textBox5);
            this.Detailes.Controls.Add(this.label8);
            this.Detailes.Controls.Add(this.label7);
            this.Detailes.Controls.Add(this.label6);
            this.Detailes.Controls.Add(this.label5);
            this.Detailes.Controls.Add(this.label4);
            this.Detailes.Controls.Add(this.label3);
            this.Detailes.Controls.Add(this.textBox1);
            this.Detailes.Controls.Add(this.textBox4);
            this.Detailes.Controls.Add(this.butTest);
            this.Detailes.Controls.Add(this.textBox2);
            this.Detailes.Controls.Add(this.textBox3);
            this.Detailes.Controls.Add(this.txtTimeTaken);
            this.Detailes.Controls.Add(this.richTextStats);
            this.Detailes.Location = new System.Drawing.Point(401, 8);
            this.Detailes.Name = "Detailes";
            this.Detailes.Size = new System.Drawing.Size(235, 352);
            this.Detailes.TabIndex = 39;
            this.Detailes.TabStop = false;
            this.Detailes.Text = "Details";
            // 
            // label9
            // 
            this.label9.Location = new System.Drawing.Point(94, 277);
            this.label9.Name = "label9";
            this.label9.Size = new System.Drawing.Size(32, 16);
            this.label9.TabIndex = 43;
            this.label9.Text = "FE2:";
            // 
            // label8
            // 
            this.label8.Location = new System.Drawing.Point(14, 277);
            this.label8.Name = "label8";
            this.label8.Size = new System.Drawing.Size(32, 16);
            this.label8.TabIndex = 42;
            this.label8.Text = "FE1:";
            // 
            // label7
            // 
            this.label7.Location = new System.Drawing.Point(14, 325);
            this.label7.Name = "label7";
            this.label7.Size = new System.Drawing.Size(56, 16);
            this.label7.TabIndex = 41;
            this.label7.Text = "Time:";
            // 
            // label6
            // 
            this.label6.Location = new System.Drawing.Point(14, 228);
            this.label6.Name = "label6";
            this.label6.Size = new System.Drawing.Size(104, 16);
            this.label6.TabIndex = 40;
            this.label6.Text = "Succession:";
            // 
            // label5
            // 
            this.label5.Location = new System.Drawing.Point(14, 196);
            this.label5.Name = "label5";
            this.label5.Size = new System.Drawing.Size(106, 16);
            this.label5.TabIndex = 39;
            this.label5.Text = "Raw set generation:";
            // 
            // label4
            // 
            this.label4.Location = new System.Drawing.Point(14, 252);
            this.label4.Name = "label4";
            this.label4.Size = new System.Drawing.Size(96, 16);
            this.label4.TabIndex = 38;
            this.label4.Text = "Pattern:";
            // 
            // label3
            // 
            this.label3.Location = new System.Drawing.Point(14, 301);
            this.label3.Name = "label3";
            this.label3.Size = new System.Drawing.Size(88, 16);
            this.label3.TabIndex = 37;
            this.label3.Text = "Clean up loop:";
            // 
            // optionsControl1
            // 
            this.optionsControl1.Location = new System.Drawing.Point(136, 8);
            this.optionsControl1.Name = "optionsControl1";
            this.optionsControl1.Size = new System.Drawing.Size(256, 160);
            this.optionsControl1.TabIndex = 0;
            // 
            // typeControl1
            // 
            this.typeControl1.Location = new System.Drawing.Point(136, 176);
            this.typeControl1.Name = "typeControl1";
            this.typeControl1.Size = new System.Drawing.Size(256, 184);
            this.typeControl1.TabIndex = 1;
            // 
            // Form1
            // 
            this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
            this.ClientSize = new System.Drawing.Size(400, 383);
            this.Controls.Add(this.optionsControl1);
            this.Controls.Add(this.typeControl1);
            this.Controls.Add(this.Detailes);
            this.Controls.Add(this.statusBar1);
            this.Controls.Add(this.butGenSample);
            this.Controls.Add(this.listBox1);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MaximizeBox = false;
            this.Menu = this.mainMenu1;
            this.Name = "Form1";
            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
            this.Text = "RandomRat v0.x";
            this.Deactivate += new System.EventHandler(this.Form1_Deactivate);
            this.Load += new System.EventHandler(this.Form1_Load);
            this.Activated += new System.EventHandler(this.Form1_Activated);
            this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel1)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel2)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.statusBarPanel3)).EndInit();
            this.Detailes.ResumeLayout(false);
            this.Detailes.PerformLayout();
            this.ResumeLayout(false);

		}
		#endregion
		[STAThread]
		static void Main() {
			Application.Run(new Form1());
		}
		#endregion



		#endregion

		#region SetArguments and validating input

		// Returns set arguments as inputed by user
		private SetArguments getUserInputtedArguments() {
			SetArguments setArgs = new SetArguments();
			
			optionsControl1.FillSetArguments(ref setArgs);
			typeControl1.FillSetArguments(ref setArgs);

			return setArgs;
		}

		
		// Returns whether curent input is valid (shows red warning icons if not)
		private bool isInputValid() {
			bool valid1 = optionsControl1.IsInputValid(true, typeControl1.TypeCount);
			bool valid2 = typeControl1.IsInputValid(true);

			return valid1 && valid2;
		}

		
		#endregion


		public bool firstActivation = true;
		private void Form1_Activated(object sender, System.EventArgs e) {
			if (firstActivation) {
				firstActivation = false;
				// Do all the stuff that shuld happen after the form loads and activates for the first time

				if (ApplicationSettings.ShowQuickStart)	showQuickStartDialog();
			}

		}
		private void Form1_Deactivate(object sender, System.EventArgs e) {

		}





		// The abbis of wappers
		private void changeHandaler(object sender, EventArgs e) {
			updateCleanStatus();
		}
		private void menFile_SetCriteriaWizard_Click(object sender, System.EventArgs e) {
			showNewCriteriaWizardDialog();
		}	
		private void menFile_Criteria_New_Click(object sender, System.EventArgs e) {
			newCriteria();
		}
		private void menView_QuickStart_Click(object sender, System.EventArgs e) {			
			showQuickStartDialog();
		}
		private void menFile_Rename_Click(object sender, System.EventArgs e) {
			this.renameCriteria();
		}

		#region Criteria menue handelers

		private void menFile_Criteria_Load_Click(object sender, System.EventArgs e) {
			this.loadCriteria();
		}
		private void menFile_Criteria_Save_Click(object sender, System.EventArgs e) {
			saveCriteria(false);
		}
		private void menFile_Criteria_SaveAs_Click(object sender, System.EventArgs e) {
			saveCriteria(true);
		}

		#endregion

		private void menView_Summary_Click(object sender, System.EventArgs e) {
			if (!menView_Summary.Checked) {
				viewSummary = new ViewSummary();
				viewSummary.SetFormState(curFormState);
				viewSummary.Show();
			} else {
				viewSummary.Close();
				viewSummary.Dispose();
			}
		}

		private void menView_Popup(object sender, System.EventArgs e) {
			if (viewSummary != null && viewSummary.Visible) {
				menView_Summary.Checked = true;
			} else {
				menView_Summary.Checked = false;
			}
		}

		private void menView_SetsViewer_Click(object sender, System.EventArgs e) {
			SetsViewer setsViewer = new SetsViewer();
			setsViewer.ShowDialog();
			setsViewer.Dispose();
		}

		private void menFile_Criteria_Popup(object sender, System.EventArgs e) {
			menFile_Criteria_Load.Enabled = dataManager.CriteriaDataSet.Tables["Criteria"].Rows.Count != 0;
		}

		private void menView_Options_Click(object sender, System.EventArgs e) {
			Settings settings = new Settings(dataManager, this);
			settings.ShowDialog();
			settings.Dispose();
		}

		private void menFile_Popup(object sender, System.EventArgs e) {
			menFile_CurSets.Enabled = lastRndSetGenerated != null;
			menFile_CurSample.Enabled = listBox1.Items.Count > 0;
		}

		private void menFile_Generate_Click(object sender, System.EventArgs e) {
			generateSetsDialog();
		}

		private void generateSetsDialog() {
			if (isInputValid()) {
				
				GenerateSets genSets = new GenerateSets(this.curFormState, this);
				genSets.ShowDialog();

				if (genSets.GeneratedSets) {
					lastRndSetGenerated = genSets.RndSets;
					setArgsForLastGeneratedSet = curFormState.ToSetArguments();;

					if (genSets.Sets != "") {
						// TODO: Could creat single assinment point for setting the Sets value
						curFormState.Sets = genSets.Sets;

						if (criteriaHasBeenSaved) {
							dataManager.SaveSets(this.curCriteriaID, genSets.Sets);
						} else {
							sets = genSets.Sets;
						}
					}
				}
				
				genSets.Dispose();
			}
		}




	}
}
